package com.wy.base;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jface.dialogs.IDialogPage;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ContainerSelectionDialog;

import com.wy.util.PluginUtils;

/**
 * 通用新建文件向导展示页面
 * 
 * @auther 飞花梦影
 * @date 2021-07-16 23:41:07
 * @git {@link https://github.com/dreamFlyingFlower}
 */
public abstract class AbstractWizardPage extends WizardPage {

	/** 工作台中当前被选中项,可以是项目,也可以是其他资源 */
	protected ISelection selection;

	/** 完整项目名 */
	protected Text projectText;

	/** 完整包名 */
	protected Text packageText;

	/** 完整类名 */
	protected Text classText;

	/** 项目是否为maven项目 */
	protected Boolean maven;

	protected AbstractWizardPage(String pageName) {
		super(pageName);
	}

	/**
	 * 构建页面视图
	 * 
	 * @param parent 上一级容器视图
	 * @see IDialogPage#createControl(Composite)
	 */
	@Override
	public void createControl(Composite parent) {
		Composite composite = buildComposite(parent);
		projectText = PluginUtils.createText(composite, "&Container:", defaultTextModifyListenter());
		Button button = new Button(composite, SWT.PUSH);
		button.setText("Browse...");
		button.addSelectionListener(defaultProjectSelectionListener());
		packageText = PluginUtils.createText(composite, "&Package Name:", defaultTextModifyListenter());
		new Label(composite, 0);
		classText = PluginUtils.createText(composite, "&Class Name:", defaultTextModifyListenter());
		additionalControl(parent, composite);
		initialize();
		defaultTextModifyListenter();
		setControl(composite);
	}

	/**
	 * 默认容器布局
	 * 
	 * @param parent 上一级容器视图
	 * @return 新的容器布局
	 */
	protected Composite buildComposite(Composite parent) {
		return buildComposite(parent, 3, 9);
	}

	/**
	 * 默认容器布局
	 * 
	 * @param parent 上一级容器视图
	 * @param numColumns 水平布局字段数
	 * @param verticalSpacing 垂直空隙
	 * @return 新的容器布局
	 */
	protected Composite buildComposite(Composite parent, int numColumns, int verticalSpacing) {
		Composite composite = new Composite(parent, SWT.NULL);
		GridLayout layout = new GridLayout();
		composite.setLayout(layout);
		layout.numColumns = numColumns;
		layout.verticalSpacing = verticalSpacing;
		return composite;
	}

	/**
	 * 使用标准容器选择对话框去选择新的容器
	 */
	protected SelectionAdapter defaultProjectSelectionListener() {
		return new SelectionAdapter() {

			public void widgetSelected(SelectionEvent e) {
				ContainerSelectionDialog dialog = new ContainerSelectionDialog(getShell(),
						ResourcesPlugin.getWorkspace().getRoot(), false, "Select new Project");
				if (dialog.open() == ContainerSelectionDialog.OK) {
					Object[] result = dialog.getResult();
					if (result.length == 1) {
						projectText.setText(((Path) result[0]).toString());
					}
				}
			}
		};
	}

	/**
	 * 其他布局内容
	 * 
	 * @param parent 最上层布局
	 * @param self 当前布局
	 */
	protected void additionalControl(Composite parent, Composite self) {
	}

	/**
	 * Tests if the current workbench selection is a suitable container to use.
	 */
	protected void initialize() {
		if (selection != null && selection.isEmpty() == false && selection instanceof IStructuredSelection) {
			IStructuredSelection ssel = (IStructuredSelection) selection;
			if (ssel.size() > 1) {
				return;
			}
			Object obj = ssel.getFirstElement();
			if (obj instanceof IResource) {
				IContainer container;
				if (obj instanceof IContainer) {
					container = (IContainer) obj;
				} else {
					container = ((IResource) obj).getParent();
				}
				projectText.setText(container.getFullPath().toString());
			} else if (obj instanceof IAdaptable) {
				IAdaptable adaptable = (IAdaptable) obj;
				IJavaElement jelem = (IJavaElement) adaptable.getAdapter(IJavaElement.class);
				if (jelem != null) {
					IJavaProject jproject = jelem.getJavaProject();
					if ((jproject != null) && (jproject.exists())) {
						projectText.setText(jproject.getElementName().replaceAll("[ \t]+", ""));
						try {
							IPackageFragmentRoot[] roots = jproject.getPackageFragmentRoots();
							for (IPackageFragmentRoot root : roots) {
								if (root.getKind() == 1) {
									this.packageText.setText(root.getPath().toString().substring(1));
									break;
								}
							}
						} catch (JavaModelException e) {
							e.printStackTrace();
						}
					}
				}
			} else if (obj instanceof IPackageFragment) {
				IPackageFragment pf = (IPackageFragment) obj;
				this.packageText.setText(pf.getElementName());
			}
		}
	}

	/**
	 * Text:监听文本编辑器中的内容变化,判断内容是否正确
	 */
	protected ModifyListener defaultTextModifyListenter() {
		return new ModifyListener() {

			@Override
			public void modifyText(ModifyEvent arg0) {
				IResource container = ResourcesPlugin.getWorkspace().getRoot().findMember(new Path(getProjectName()));
				String packageName = getPackageName();
				String fileName = getClassName();

				checkName("Project", getProjectName());

				if (container == null || (container.getType() & (IResource.PROJECT | IResource.FOLDER)) == 0) {
					updateStatus("Project must exist");
					return;
				}
				if (!container.isAccessible()) {
					updateStatus("Project must be writable");
					return;
				}

				checkName("Pacakge", packageName);
				checkName("Class", fileName);
				try {
					IJavaProject project =
							(IJavaProject) container.getProject().getNature("org.eclipse.jdt.core.javanature");
					IPackageFragmentRoot[] packages = project.getAllPackageFragmentRoots();
					for (IPackageFragmentRoot ipfr : packages) {
						IPackageFragment ipackage;
						if ((ipackage = ipfr.getPackageFragment(packageName)) != null) {
							if (!ipackage.getCompilationUnit(fileName + ".java").exists())
								break;
							updateStatus("Class already exists");
							return;
						}
					}
				} catch (CoreException ce) {
					ce.printStackTrace();
				}
				updateStatus(null);
				return;
			}
		};
	}

	/**
	 * 检查项目名,包名,类名是否合法
	 * 
	 * @param name 待检查的名称
	 */
	protected void checkName(String type, String name) {
		if (name.isEmpty()) {
			updateStatus(type + " name must be specified");
			return;
		}
		if (name.endsWith(".")) {
			updateStatus(type + " name must be valid");
			return;
		}
		if (name.replace('\\', '/').indexOf('/', 1) > 0) {
			updateStatus(type + " name must be valid");
			return;
		}
		if (type.equalsIgnoreCase("class")) {
			int dotLoc = name.lastIndexOf('.');
			if (dotLoc != -1) {
				String ext = name.substring(dotLoc + 1);
				if (!ext.equalsIgnoreCase("java")) {
					updateStatus("Class extension must be \"java\"");
					return;
				}
			}
		}
	}

	/**
	 * 弹出错误信息
	 * 
	 * @param message 信息
	 */
	protected void updateStatus(String message) {
		setErrorMessage(message);
		setPageComplete(message == null);
	}

	public String getProjectName() {
		return projectText.getText();
	}

	public String getPackageName() {
		return packageText.getText();
	}

	public String getClassName() {
		return classText.getText();
	}
}